#pragma once

#ifdef main
#undef main
#endif // main

#include <lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/tag_function.hpp>
#include <luabind/detail/policy.hpp>

#include <vector>

using namespace std;

namespace luabind
{
    template <class T>
    struct default_converter<vector<T> >
        : native_converter_base<vector<T> >
    {
        static int compute_score(lua_State* L, int index)
        {
            return (lua_type(L, index) == LUA_TTABLE )? 0 : -1;
        }

        vector<T>  from(lua_State* L, int index)
        {
            vector<T> container;
            luabind::object tbl(from_stack(L, index));

            for (luabind::iterator itr(tbl), end; itr != end; ++itr)
            {
                boost::optional<T> v = object_cast_nothrow<T>(*itr);
                if (v){
                    container.push_back(*v);
                }
            }

            return container;
        }

        typedef typename vector<T>::const_iterator const_iterator;

        void to(lua_State* L, vector<T>  const& container)
        {
            lua_createtable(L, container.size(), 0);

            luabind::object tbl(from_stack(L, -1));
            int n = 0;

            for (const_iterator itr = container.begin(); itr != container.end(); ++itr)
            {
                tbl[++n] = *itr;
            }
        }
    };

    template <class T>
    struct default_converter<vector<T>  const&>
        : default_converter<vector<T> >
    {};
}
